package com.three.iot.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.three.iot.api.DeviceService;
import com.three.iot.api.ProductAttrService;
import com.three.iot.api.ProductService;
import com.three.iot.channel.api.DeviceChannelService;
import com.three.iot.channel.po.DeviceCondPo;
import com.three.iot.channel.po.DeviceRespPo;
import com.three.iot.commons.constant.CommonConstants;
import com.three.iot.commons.dto.DeviceCondDto;
import com.three.iot.commons.dto.ProductAttrRespDto;
import com.three.iot.commons.enums.Result;
import com.three.iot.commons.enums.ResultCode;
import com.three.iot.commons.po.UserInfo;
import com.three.iot.commons.utils.DateUtil;
import com.three.iot.commons.dto.DeviceRespDto;
import com.three.iot.jdbc.mapper.TDeviceInfoMapper;
import com.three.iot.jdbc.model.TDeviceInfo;
import com.three.iot.jdbc.model.TProductAttr;
import com.three.iot.jdbc.model.TProductInfo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author luiz
 * @Title: DeviceServiceImpl
 * @ProjectName iot-server
 * @Description: TODO
 * @date 2019-06-13 17:44
 */
@Service
public class DeviceServiceImpl implements DeviceService {
    @Resource
    TDeviceInfoMapper tDeviceInfoMapper;
    @Resource
    DeviceChannelService deviceChannelService;
    @Resource
    ProductService productService;
    @Resource
    ProductAttrService productAttrService;

    @Override
    public Page<DeviceRespDto> listPage(DeviceCondDto deviceCondDto) {
        //使用PageHelper类进行分页
        PageHelper.startPage(deviceCondDto.getPageNum(), deviceCondDto.getPageSize());
        Page<TDeviceInfo> devicePage = (Page<TDeviceInfo>) tDeviceInfoMapper.selectList(deviceCondDto);
        Page<DeviceRespDto> deviceRespDtoPage=new Page<DeviceRespDto>();
        BeanUtils.copyProperties(devicePage,deviceRespDtoPage);
        List<TDeviceInfo> deviceInfos=devicePage.getResult();
        for(TDeviceInfo deviceInfo:deviceInfos){
            DeviceRespDto deviceRespDto=buildDto(deviceInfo);
            deviceRespDtoPage.add(deviceRespDto);
        }
        return deviceRespDtoPage;
    }

    private DeviceRespDto buildDto(TDeviceInfo deviceInfo) {
        DeviceRespDto deviceRespDto=new DeviceRespDto();
        BeanUtils.copyProperties(deviceInfo,deviceRespDto);
        deviceRespDto.setActiveTime(DateUtil.getDateTimeFormat(deviceInfo.getActiveTime()));
        deviceRespDto.setAddTime(DateUtil.getDateTimeFormat(deviceInfo.getAddTime()));
        deviceRespDto.setLastOnlineTime(DateUtil.getDateTimeFormat(deviceInfo.getLastOnlineTime()));
        return deviceRespDto;
    }

    @Override
    public void refresh(UserInfo userInfo) {
        //刷新产品列表
        productService.refreshProduct(1,userInfo.getUserNo());
        List<TProductInfo> productInfos=productService.findAll();
        for(TProductInfo tProductInfo:productInfos){
            //获取设备列表
            refreshDevice(1,tProductInfo.getProductKey(),userInfo.getUserNo());
        }
    }

    @Override
    public List<TDeviceInfo> listAll() {
        return tDeviceInfoMapper.selectAll();
    }

    @Override
    public List<DeviceRespDto> listLike(String codStr) {
        List<TDeviceInfo> tDeviceInfos = tDeviceInfoMapper.selectLike(codStr);
        List<DeviceRespDto> deviceRespDtoList=new ArrayList<>();
        for(TDeviceInfo tDeviceInfo:tDeviceInfos){
            DeviceRespDto deviceRespDto=buildDto(tDeviceInfo);
            deviceRespDtoList.add(deviceRespDto);
        }
        return deviceRespDtoList;
    }

    @Override
    public Result findAttrByIotId(String iotId) {
        TDeviceInfo tDeviceInfo=tDeviceInfoMapper.selectByIotId(iotId);
        if(tDeviceInfo==null){
            return Result.newError(ResultCode.COMMON_DATA_NOT_EXISTS);
        }
        String productKey=tDeviceInfo.getProductKey();
        return  productAttrService.findAttrListByProducKey(productKey);
    }

    @Override
    public ProductAttrRespDto findAttrByIotIdAndAttrNo(String iotId, String attrNo) {
        TDeviceInfo tDeviceInfo=tDeviceInfoMapper.selectByIotId(iotId);
        if(tDeviceInfo==null){
            return null;
        }
        String productKey=tDeviceInfo.getProductKey();
        return  productAttrService.findAttrByIndex(productKey,attrNo);
    }

    private void refreshDevice(int pageNum,String productKey,String userNo) {
        DeviceCondPo deviceCondPo=new DeviceCondPo();
        deviceCondPo.setProductKey(productKey);
        deviceCondPo.setPageNum(pageNum);
        deviceCondPo.setPageSize(CommonConstants.DEFAULT_PAGE_SIZE);
        listDevice(deviceCondPo,userNo);
    }


    private void listDevice(DeviceCondPo deviceCondPo,String userNo){
        Result<Page<DeviceRespPo>>  deviceRespPoPageResult=deviceChannelService.findDeviceList(deviceCondPo);
        if(deviceRespPoPageResult.isSuccess()){
            Page<DeviceRespPo> deviceRespPoPage=deviceRespPoPageResult.getData();
            List<DeviceRespPo> deviceRespPos =deviceRespPoPage.getResult();
            //更新设备信息
            saveDeviceInfo(deviceRespPos,userNo);
            int totalPageNum=deviceRespPoPage.getPages();
            int currentPageNum=deviceRespPoPage.getPageNum();
            if(totalPageNum>currentPageNum){
                deviceCondPo.setPageNum(currentPageNum+1);
                //递归遍历
                listDevice(deviceCondPo,userNo);
            }
        }
    }

    /**
     * 存储设备信息
     * @param deviceRespPos
     */
    private void saveDeviceInfo(List<DeviceRespPo> deviceRespPos,String userNo) {
        for(DeviceRespPo deviceRespPo:deviceRespPos){
            TDeviceInfo tDeviceInfo=new TDeviceInfo();
            BeanUtils.copyProperties(deviceRespPo,tDeviceInfo);
            tDeviceInfo.setDeviceNickName(deviceRespPo.getNickname());
            tDeviceInfo.setAddTime(DateUtil.pareDate(deviceRespPo.getUtcCreate()));
            tDeviceInfo.setCreateTime(new Date());
            tDeviceInfo.setModiTime(new Date());
            tDeviceInfo.setModiNo(userNo);
            save(tDeviceInfo);
        }
    }
    private void save(TDeviceInfo tDeviceInfo) {
        TDeviceInfo tDeviceInfo1=tDeviceInfoMapper.selectByIotId(tDeviceInfo.getIotId());
        if(tDeviceInfo1!=null){
            tDeviceInfo.setId(tDeviceInfo1.getId());
            tDeviceInfo.setModiTime(new Date());
            tDeviceInfoMapper.updateByPrimaryKeySelective(tDeviceInfo);
        }else {
            tDeviceInfo.setCreateNo(tDeviceInfo.getModiNo());
            tDeviceInfo.setCreateTime(new Date());
            tDeviceInfo.setModiTime(new Date());
            tDeviceInfoMapper.insertSelective(tDeviceInfo);
        }
    }

}
